package com.syxd.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.syxd.common.constant.Constant;
import com.syxd.common.entity.WebResult;
import com.syxd.common.exception.ErrorCode;
import com.syxd.common.service.impl.CrudServiceImpl;
import com.syxd.common.utils.*;
import com.syxd.dao.SysUserDao;
import com.syxd.dto.SysPermissionDTO;
import com.syxd.dto.SysUserDTO;
import com.syxd.entity.SysUserEntity;
import com.syxd.service.SysUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

@Service
@Transactional
public class SysUserServiceImpl extends CrudServiceImpl<SysUserDao, SysUserEntity, SysUserDTO> implements SysUserService {
    @Value("${frontEnd.domain}")
    private String domain;
    @Autowired
    JedisUtil jedisUtil;
    @Autowired
    SysUserDao sysUserDao;

    @Override
    public QueryWrapper<SysUserEntity> getWrapper(Map<String, Object> params) {
        QueryWrapper<SysUserEntity> wrapper = new QueryWrapper<>();
        String id = (String) params.get("userId");

        wrapper.eq(StringUtils.isNotBlank(id), " user_id", id);
        String branchName = (String) params.get("branchName");
        wrapper.eq(StringUtils.isNotBlank(branchName), "branch_name", branchName);
        String loginAccount = (String) params.get("loginAccount");
        wrapper.like(StringUtils.isNoneBlank(loginAccount), "BINARY login_account", loginAccount);
        String userRoleId = (String) params.get("userRoleId");
        wrapper.eq(StringUtils.isNotBlank(userRoleId), "user_role_id", userRoleId);
        String userState = (String) params.get("userState");
        wrapper.eq(StringUtils.isNotBlank(userState), "user_state", userState);
        String phone = (String) params.get("phone");
        wrapper.like(StringUtils.isNotBlank(phone), "phone", phone);

        wrapper.eq(true,"is_delete",0);
        return wrapper;
    }

    @Override
    public WebResult getInfoFromToken(HttpServletRequest request, String name) {
        WebResult<Object> result = new WebResult<>();
        String token = null;
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (StringUtils.equals(cookie.getName(), Constant.TOKEN_HEADER)) {
                    token = cookie.getValue();

                }
            }
        }
        token = request.getHeader(Constant.TOKEN_HEADER);
        String loginAccount = jedisUtil.getString(Constant.REDIS_TOKEN_KEY + token);
        String data = jedisUtil.hget(Constant.REDIS_USER_KEY + loginAccount, name);
        return result.ok(data);
    }

    @Override
    public Set<String> getUserPermissions(UserDetail userDetail) {
        String permissions = jedisUtil.getString(Constant.REDIS_PERMISSION_KEY + userDetail.getUserId());
        Set<String> result = new HashSet<>();
        if (StringUtils.isNotBlank(permissions)) {
            result.addAll(Arrays.asList(permissions.trim().split(",")));
        } else {
            List<String> userPermissions = sysUserDao.getUserPermissions(userDetail.getUserId());

            if (userPermissions != null && userPermissions.size() > 0) {
                for (int i = 0; i < userPermissions.size(); i++) {
                    String permission = userPermissions.get(i);
                    if (StringUtils.isNotBlank(permission)) {
                        result.addAll(Arrays.asList(permission.trim().split(",")));
                    }
                }
            }
            System.out.println(result.toString());
            permissions = StringUtils.strip(result.toString(), "[]");
            jedisUtil.setExString(Constant.REDIS_PERMISSION_KEY + userDetail.getUserId(), Constant.REDIS_TOKEN_TIMEOUT, permissions);
        }
        return result;
    }

    @Override
    public WebResult getUserPermissionsByToken(String token) {
        String loginAccount = jedisUtil.getString(Constant.REDIS_TOKEN_KEY + token);
        Map<String, String> userInfo = jedisUtil.hgetAll(Constant.REDIS_USER_KEY + loginAccount);
        String userId = userInfo.get("userId");
        List<SysPermissionDTO> userPermissionsDetail = sysUserDao.getUserPermissionsDetail(userId);
        HashMap<String, Object> map = new HashMap<>();
        map.put("userInfo", userInfo);
        map.put("userPermissionsDetail", userPermissionsDetail);
        return new WebResult().ok(map);
    }

    @Override
    public UserDetail getByToken(String token) {
        UserDetail userDetail = null;
        if (StringUtils.isNotBlank(token)) {
            String loginAccount = jedisUtil.getString(Constant.REDIS_TOKEN_KEY + token);
            if (StringUtils.isBlank(loginAccount)) {
                return userDetail;
            }
            userDetail = new UserDetail();
            Map<String, String> userInfo = jedisUtil.hgetAll(Constant.REDIS_USER_KEY + loginAccount);
            userDetail.setLoginAccount(userInfo.get("loginAccount"));
            userDetail.setUserId(Integer.valueOf(userInfo.get("userId")));
            userDetail.setUserState(Integer.valueOf(userInfo.get("userState")));
            userDetail.setUserName(userInfo.get("userName"));
            userDetail.setUserRoleName(userInfo.get("userRoleName"));
            userDetail.setUserRoleId(Integer.valueOf(userInfo.get("userRoleId")));
        }

        return userDetail;
    }

    /**
     * 登录
     *
     * @param response
     * @param login
     * @return
     */
    @Override
    public WebResult login(HttpServletResponse response, SysUserDTO login) {
        WebResult result = new WebResult();
        Map<String, Object> map = new HashMap<>(2);
        List<SysUserDTO> userInfoList = null;
        try {
            userInfoList = sysUserDao.selectByLoginAccount(login.getLoginAccount());
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (userInfoList != null && userInfoList.size() > 0) {
            //每次登录都要重新存用户数据，因为可以更改用户状态
         //   String token = jedisUtil.hget(Constant.REDIS_USER_KEY + login.getLoginAccount(), "token");
            String token="";
            SysUserDTO sysUserDTO = userInfoList.get(0);
            if (sysUserDTO.getLoginPassword().equals(MD5Util.md5(login.getLoginPassword()))) {
                String loginAccount = jedisUtil.get(Constant.REDIS_TOKEN_KEY + token);
                if (StringUtils.isBlank(token) || StringUtils.isBlank(loginAccount)) {
                    token = TokenGenerator.generateValue();
                    Map userInfo = new HashMap<String, String>();
                    userInfo.put("loginAccount", sysUserDTO.getLoginAccount());
                    userInfo.put("token", token);
                    userInfo.put("userId", String.valueOf(sysUserDTO.getUserId()));
                    userInfo.put("userName", StringUtils.isBlank(sysUserDTO.getUserName()) ? StringUtils.EMPTY : sysUserDTO.getUserName());
                    userInfo.put("userRoleName", sysUserDTO.getUserRoleName());
                    userInfo.put("userRoleId", String.valueOf(sysUserDTO.getUserRoleId()));
                    userInfo.put("userState", String.valueOf(sysUserDTO.getUserState()));
                    userInfo.put("phone", /*String.valueOf(sysUserDTO.getPhone())*/StringUtils.isBlank(sysUserDTO.getPhone())?StringUtils.EMPTY:sysUserDTO.getPhone());
                    jedisUtil.setExString(Constant.REDIS_TOKEN_KEY + token, Constant.REDIS_TOKEN_TIMEOUT, login.getLoginAccount());

                    jedisUtil.hmset(Constant.REDIS_USER_KEY + login.getLoginAccount(), userInfo);
                }
            } else {
                return result.error(ErrorCode.ACCOUNT_PASSWORD_ERROR);
            }
            map.put(Constant.TOKEN_HEADER, token);
            Cookie cookie = new Cookie(Constant.TOKEN_HEADER, token);
            cookie.setHttpOnly(false);
            cookie.setDomain(domain);
            cookie.setPath("/");
            cookie.setMaxAge(Integer.MAX_VALUE);
            response.addCookie(cookie);
        } else {
            return result.error(ErrorCode.ACCOUNT_NOT_EXIST);
        }
        return result.ok(map);
    }

    /**
     * 登出
     * @param request
     * @return
     */
    @Override
    public WebResult logout(HttpServletRequest request) {
        // 清空 redis中用户信息
        String token = null;
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (StringUtils.equals(cookie.getName(), Constant.TOKEN_HEADER)) {
                    token = cookie.getValue();

                }
            }
        }
        token = request.getHeader(Constant.TOKEN_HEADER);
        jedisUtil.del(Constant.REDIS_TOKEN_KEY + token);
        return new WebResult();
    }

    @Override
    public void saveInfo(SysUserDTO dto) {
        SysUserEntity sysUserEntity = BeanHelper.copyProperties(dto, SysUserEntity.class);

        baseDao.insert(sysUserEntity);

    }

    @Override
    public List<SysUserDTO> selectByLoginAccount(String loginAccount) {
     return    sysUserDao.selectByLoginAccount(loginAccount);
    }
    @Override
    public WebResult changePassword(SysUserDTO changeDto, HttpServletRequest request) {
        WebResult<Object> result = new WebResult<>();
        String token = null;
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (StringUtils.equals(cookie.getName(), Constant.TOKEN_HEADER)) {
                    token = cookie.getValue();

                }
            }
        }
        token = request.getHeader(Constant.TOKEN_HEADER);
        String loginAccount = jedisUtil.getString(Constant.REDIS_TOKEN_KEY + token);
        String userId = jedisUtil.hget(Constant.REDIS_USER_KEY + loginAccount, "userId");
        SysUserEntity sysUserEntity1 = baseDao.selectById(Long.valueOf(userId));
        SysUserDTO sysUserDTO = BeanHelper.copyProperties(sysUserEntity1, SysUserDTO.class);
        if(!sysUserDTO.getLoginPassword().equals(MD5Util.md5(changeDto.getOldPassword()))) {
            return result.error(ErrorCode.OLD_PASSWORD_ERROR);
        }
//        if (!changeDto.getLoginPassword().equals(changeDto.getConfirmPassword())) {
//            return result.error(ErrorCode.CONFIRM_PASSWORD_ERROR);
//        }
        SysUserEntity sysUserEntity = new SysUserEntity();
        sysUserEntity.setLoginPassword(MD5Util.md5(changeDto.getLoginPassword()));
        sysUserEntity.setUserId(Integer.valueOf(userId));
        sysUserEntity.setPhone(changeDto.getPhone());
        updateById(sysUserEntity);
        jedisUtil.del(Constant.REDIS_TOKEN_KEY + token);
        return result;
    }

    @Override
    public void delete(Long[] ids, Integer userId) {
        for (int i=0;i<ids.length;i++) {
            Map<String, Object> map = new HashMap<>();
            map.put("updateBy",userId);
            map.put("userId",ids[i]);

            baseDao.logicDelete(map);
        }
    }
}
